#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<dirent.h>
#include<sys/stat.h>
#include<time.h>
#include<unistd.h>

#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<random>
using namespace std;

class Execute{

public:

    Execute(){}

    ~Execute(){
        while (!shell_command.empty()) {
            shell_command.erase(shell_command.begin());
        }
    }

    void travel_dir(const char* path){
        DIR *d;
        struct dirent* file = new dirent();
        struct stat* st = new struct stat();
        if(!(d = opendir(path))){ // 打不开指定的起始文件夹
            printf("erroe dirs %s!!!\n", path);
            return;
        }

        while((file = readdir(d)) != NULL){
            // 跳过隐藏文件, 当前目录(.),或上一级目录
            if(strncmp(file->d_name, ".", 1) == 0)
                continue;
            //如果是普通的文件
            if(file->d_type == 8){
                char* dir_prefix = (char *)malloc(strlen(path) + strlen(file->d_name) + 2);
                memset(dir_prefix, '\0', sizeof(dir_prefix));
                strcat(dir_prefix, path);
                strcat(dir_prefix, "/");

                string file_name = file->d_name;
                if(strncmp(file_name.substr(file_name.length()-3,file_name.length()).c_str(), \
                           "cpp", 3) == 0){

                    file_name = file_name.substr(0, file_name.length()-4);

                    //shell_command.push_back("cd " + string(dir_prefix));
                    shell_command.push_back(string(file_name));
                    shell_command.push_back(string(dir_prefix));
                    shell_command.push_back("g++ " + file_name + ".cpp -o " + file_name + ".out");
                    shell_command.push_back("./" + file_name + ".out <input.txt >" + file_name + ".txt");
                    //shell_command.push_back("cd ../..");

                }
            }
            //如果是文件夹
            if(file->d_type == 4){
                char* dir_path = (char *)malloc(strlen(path) + strlen(file->d_name) + 2);
                memset(dir_path, '\0', sizeof(dir_path));
                strcat(dir_path, path);
                strcat(dir_path, "/");
                strcat(dir_path, file->d_name);
                travel_dir(dir_path);
            }
        }
        closedir(d);
        return;
    }


    void execute(){
        for(vector<string>::iterator shell_commandIt = shell_command.begin(); shell_commandIt != shell_command.end();){

            string file_name = *shell_commandIt;
            shell_commandIt++;

            chdir((*shell_commandIt).c_str());
            shell_commandIt++;

            system((*shell_commandIt).c_str());
            shell_commandIt++;

            int status = system((*shell_commandIt).c_str());
            shell_commandIt++;
            if (-1 == status || !WIFEXITED(status) || WEXITSTATUS(status)){
                system(("rm -f " + file_name + ".txt").c_str());
            }
            
            chdir("../..");
        } 
    }

private:
    vector<string> shell_command;
    
};

// int main(){
//     Execute *execute = new Execute();

//     execute->travel_dir("./input");
//     execute->execute();

//     delete execute;
// }